package com.gitee.wsl.mathematics.vector.ext

import com.gitee.wsl.mathematics.number.compareTo
import com.gitee.wsl.mathematics.vector.vec2.Vector2
import com.gitee.wsl.mathematics.vector.vec3.Vector3
import com.gitee.wsl.mathematics.vector.vec4.Vector4

fun<T:Number,V: Vector2<T, V>> Math.interpolate(a: Vector2<T, V>, b: Vector2<T, V>, blend: Float): V = with(a){
    val dot =  a.x * b.x + a.y * b.y
    val blendI = one - blend
    return if (dot < zero) {
        val x = blendI * a.x + blend * -b.x
        val y = blendI * a.y + blend * -b.y
        create(x, y)
    } else {
        val x = blendI * a.x + blend * b.x
        val y = blendI * a.y + blend * b.y
        create(x, y)
    }
}

fun<T:Number,V: Vector3<T, V>> Math.interpolate(a: Vector3<T, V>, b: Vector3<T, V>, blend: Float): V = with(a){
    val dot =  a.x * b.x + a.y * b.y + a.z * b.z
    val blendI = one - blend
    return if (dot < zero) {
        val x = blendI * a.x + blend * -b.x
        val y = blendI * a.y + blend * -b.y
        val z = blendI * a.z + blend * -b.z
        create(x, y, z)
    } else {
        val x = blendI * a.x + blend * b.x
        val y = blendI * a.y + blend * b.y
        val z = blendI * a.z + blend * b.z
        create(x, y, z)
    }
}

fun<T:Number,V: Vector4<T, V>> Math.interpolate(a: Vector4<T, V>, b: Vector4<T, V>, blend: Float): V = with(a){
    val dot = a.w * b.w + a.x * b.x + a.y * b.y + a.z * b.z
    val blendI = one - blend
    return if (dot < zero) {
        val w = blendI * a.w + blend * -b.w
        val x = blendI * a.x + blend * -b.x
        val y = blendI * a.y + blend * -b.y
        val z = blendI * a.z + blend * -b.z
        create(x, y, z, w)
    } else {
        val w = blendI * a.w + blend * b.w
        val x = blendI * a.x + blend * b.x
        val y = blendI * a.y + blend * b.y
        val z = blendI * a.z + blend * b.z
        create(x, y, z, w)
    }
}


/**
 * fun endShape(canvas: Canvas, paint: Paint) {
 *             if (points.size < 4) {
 *                 return  // 至少需要4个点才能生成曲线
 *             }
 *             val path = Path()
 *             for (i in 0..points.size - 4) {
 *                 val p0 = points[i]
 *                 val p1 = points[i + 1]
 *                 val p2 = points[i + 2]
 *                 val p3 = points[i + 3]
 *
 *                 for (i in 0..(1/diff).toInt()) {
 *                     if (i == 0) {
 *                         path.lineTo(p1.x, p1.y)
 *                     }
 *                     val point = catmullRomInterpolation(p0, p1, p2, p3, i*diff)
 *                     path.lineTo(point.x, point.y)
 *                 }
 *             }
 *             canvas.drawPath(path, paint)
 *         }
 */
// catmull-rom 计算，张力默认 0.5
fun<T:Number,V: Vector2<T, V>> Math.catmullRomInterpolation(
    p0: Vector2<T, V>,
    p1: Vector2<T, V>,
    p2: Vector2<T, V>,
    p3: Vector2<T, V>,
    t: Float
): V = with(p0){
    // 计算 x 坐标
    val x = 0.5f * (
            (2 * p1.x) +
                    (-p0.x + p2.x) * t +
                    (2 * p0.x - 5 * p1.x + 4 * p2.x - p3.x) * t * t +
                    (-p0.x + 3 * p1.x - 3 * p2.x + p3.x) * t * t * t
            )

    // 计算 y 坐标
    val y = 0.5f * (
            (2 * p1.y) +
                    (-p0.y + p2.y) * t +
                    (2 * p0.y - 5 * p1.y + 4 * p2.y - p3.y) * t * t +
                    (-p0.y + 3 * p1.y - 3 * p2.y + p3.y) * t * t * t
            )

    return create(x, y)
}